home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
QuickTime 1.0 for Developers
/
QuickTime 1.0 for Developers.iso
/
Programming Stuff
/
vdig sample
/
DIGIUtils.c
next >
Wrap
C/C++ Source or Header
|
1991-09-05
|
11KB
|
398 lines
/*
File: DIGIUtils.c
*/
/* Digitizer Utilities DIGIUtils.c */
#include <QuickDraw.h>
#include "Components.h"
#include "DIGIUtils.h"
#include "video digitizer.h"
/*#include "moonraker.h"*/
#include "RO364.h"
/* #include "TSdigi.h" */
#include "Matrix.h"
#include "errHandler.h"
pascal long TestBuffers(void);
#define WITHMATRIX /* define it if you want to use the simplest interface to the digitizer */
extern ComponentInstance gti;
extern Component gt;
extern Boolean ghFlipState, gvFlipState;
pascal void ValidatePixMap(PixMapHandle *pm, Rect *r, short *tx, short *ty)
{
Rect tmpDstRect; /* temp that holds the incoming rect */
Rect iRect; /* holds the intersect rect on the gdevice */
PixMap screenPixMap; /* ultimately holds the pix map to be returned */
PixMapHandle tmpDstPixMapHandle;
short w; /* incoming rect width */
short h; /* incoming rect height */
Boolean allOn; /* true if the rect is completely contained on the gdevice */
Boolean crossScreens; /* true if the rect crosses screens */
Point tmpPoint;
GDHandle gdh;
short top;
short left;
Rect aRect;
tmpDstRect = *r;
tmpDstPixMapHandle = *pm;
screenPixMap = **tmpDstPixMapHandle;
w = r->right - r->left;
h = r->bottom - r->top;
allOn = FALSE;
crossScreens = FALSE;
if ( (*tmpDstPixMapHandle)->baseAddr == (*(Ptr *) 0x824) ) {
top = (*tmpDstPixMapHandle)->bounds.top;
left = (*tmpDstPixMapHandle)->bounds.left;
RectLocalToGlobal(&tmpDstRect);
SetPt(&tmpPoint, tmpDstRect.left, tmpDstRect.top);
gdh = GetDeviceList();
while ((gdh) != 0L && (PtInRect(tmpPoint, &(*gdh)->gdRect) != true) ) {
gdh = GetNextDevice(gdh);
}
SectRect(&tmpDstRect, &(*gdh)->gdRect, &iRect);
if (EqualRect(&tmpDstRect, &iRect)) allOn = TRUE;
screenPixMap = **(*gdh)->gdPMap;
***pm = screenPixMap;
aRect = *r;
RectLocalToGlobal(&aRect);
*tx = aRect.left;
*ty = aRect.top;
}
}
pascal void CalculateScale(Rect *r1, Rect *r2, Fixed *sx, Fixed *sy)
/* This routine takes two rects and calculates the scaling coefficients Sx and Sy.
The order is to scale r1 by Sx and Sy to get r2.
*/
{
short h1,w1,h2,w2;
h1 = r1->bottom - r1->top;
w1 = r1->right - r1->left;
h2 = r2->bottom - r2->top;
w2 = r2->right - r2->left;
*sx = FixRatio(w2,w1);
*sy = FixRatio(h2,h1);
}
pascal WindowPtr GetNewVWindow(short windowID, Ptr wStorage, WindowPtr behind)
{
Str255 defType = "\pvdig";
Str255 defSubType = "\props";
Str255 defManu = "\props";
ComponentDescription foo;
long result = 0;
Rect r;
Rect activeRect;
WindowPtr vidWindow;
long aaa, bbb;
vidWindow = GetNewCWindow(windowID,wStorage,behind); /* Make a new window */
/* First find a digitizer thing and open it */
foo.componentType = videoDigitizerComponentType;
foo.componentSubType = 0;
foo.componentManufacturer = 0;
foo.componentFlags = 0;
foo.componentFlagsMask = 0;
/*Use this one if the thing is built into project*/
gt = RegisterComponent(&foo, (void *)RO364Thing, 1, 0, 0, 0);
/* Use this one if using a real thing *//**/
/* gt = FindNextComponent((Component)0x0L,&foo); */
gti = OpenComponent(gt);
/* Initialize the digitizer to full screen and digitizing off */
result = VDGetMaxSrcRect(gti,ntscIn,&r);
result = VDGetActiveSrcRect(gti,ntscIn,&activeRect);
result = VDSetDigitizerRect(gti,&activeRect);
result = VDSetPlayThruOnOff(gti,vdPlayThruOff);
if (result == 0) result = VDGetCurrentFlags(gti,&aaa, &bbb);
/* Do what it takes to change the video digitizer */
result = UpdateVDDestination(vidWindow);
if (result == 0) result = VDSetPlayThruOnOff(gti,vdPlayThruOn);
/* Throw up an alert if there was a problem */
if (result)ErrAlert(result,(char *)"\pNewVideoWindow");
return (vidWindow);
}
pascal void DragVideoWindow(WindowPtr theWindow, Point startPt, Rect *dragRect)
{
short tx;
short ty;
long result = 0;
Rect r;
MatrixRecord aMatrix;
DigitizerInfo digiInfo;
Fixed ftx, fty, sx, sy;
PixMapHandle aPixMapHandle;
long aaa, bbb;
PicHandle picH;
short qderr;
GDHandle savegdh;
/* Freeze video so drag update will work right and do the inherited DragWindow */
if (result == 0) result = VDSetPlayThruOnOff(gti,vdPlayThruOff);
DragWindow(theWindow, startPt, dragRect);
/* Do what it takes to change the video digitizer */
result = UpdateVDDestination(theWindow);
/* Turn on the digitizer at the new location if all is well */
if (result == 0) result = VDSetPlayThruOnOff(gti,vdPlayThruOn);
/* Test the VDSetupBuffers stuff */
if (result == 0) result = TestBuffers();
/* Throw up an alert if there was a problem */
if (result)ErrAlert(result,(char *)"\pDragVideoWindow");
}
pascal void GrowVideoWindow(WindowPtr theWindow, Point startPt)
{
long result = 0;
long theResult;
Rect r;
/* Freeze video so drag update will work right and do the inherited GrowWindow (with dragRect limited to MaxSrcRect) */
if (result == 0) result = VDSetPlayThruOnOff(gti,vdPlayThruOff);
result = VDGetMaxSrcRect(gti,ntscIn,&r);
theResult = GrowWindow( theWindow, startPt, &r );
/* If there was no resizing operation, just exit and turn the digitizer back on (now this will work like a frame grab */
if (theResult == 0) {
if (result == 0) result = VDSetPlayThruOnOff(gti,vdPlayThruOff);
return;
}
/* Do the inherited SizeWindow after GrowWindow complete */
SizeWindow( theWindow, LoWord(theResult), HiWord(theResult), 1);
/* InvalRect(&theWindow->portRect); */
/* Do what it takes to change the video digitizer */
result = UpdateVDDestination(theWindow);
/* Turn on the digitizer with the new size if all is well */
if (result == 0) result = VDSetPlayThruOnOff(gti,vdPlayThruOn);
/* Throw up an alert if there was a problem */
if (result)ErrAlert(result,(char *)"\pGrowVideoWindow");
}
pascal void DisposeVideoWindow(WindowPtr theWindow)
{
long result = 0;
result = VDSetPlayThruOnOff(gti,vdPlayThruOff); /* Freeze video so drag update will work right */
DisposeWindow(theWindow);
CloseComponent(gti);
}
pascal void MoveVideoWindow(WindowPtr theWindow, short h, short v, Boolean front)
{
long result = 0;
/* Freeze video so drag update will work right and do the inherited MoveWindow */
result = VDSetPlayThruOnOff(gti,vdPlayThruOff);
MoveWindow(theWindow,h,v,front);
/* Do what it takes to change the video digitizer */
result = UpdateVDDestination(theWindow);
/* Turn on the digitizer with the new location if all is well */
if (result == 0) result = VDSetPlayThruOnOff(gti,vdPlayThruOn);
/* Throw up an alert if there was a problem */
if (result)ErrAlert(result,(char *)"\pMoveVideoWindow");
}
pascal long UpdateVDDestination( WindowPtr theWindow )
{
short tx;
short ty;
long result = 0;
Rect r;
Rect r1;
Rect aRect;
MatrixRecord aMatrix;
DigitizerInfo digiInfo;
Fixed ftx, fty, sx, sy;
PixMapHandle aPixMapHandle;
/* Allocate a temporary pixmap and preflight it (getting a new pixmap, tx, and ty) */
aPixMapHandle = (PixMapHandle) NewHandle( sizeof(PixMap) );
**aPixMapHandle = **((CWindowPtr)theWindow)->portPixMap;
ValidatePixMap(&aPixMapHandle, &theWindow->portRect, &tx, &ty);
#ifdef WITHMATRIX
/* Convert translation coefficients to fixed */
ftx = FixRatio(tx,1);
fty = FixRatio(ty,1);
/* Calculate the scaling coefficients and set up the transformation matrix (scale and translate */
if (result == 0) result = VDGetDigitizerRect(gti,&r);
RectMatrix(&aMatrix,&r,&(*theWindow).portRect);
if (ghFlipState) aMatrix.matrix[0][0] = -aMatrix.matrix[0][0];
if (gvFlipState) aMatrix.matrix[1][1] = -aMatrix.matrix[1][1];
TranslateMatrixTo( &aMatrix, ftx, fty);
/* Set the digitizers destination */
if (result == 0) result = VDSetPlayThruDestination(gti, aPixMapHandle, &theWindow->portRect, &aMatrix, 0L);
#else
/* A simpler interface for playthrough might be (play thru state on/off is retained in the call) */
aRect = theWindow->portRect;
RectLocalToGlobal(&aRect);
if (result == 0) result = VDSetPlayThruDestination(gti, aPixMapHandle, &aRect, 0L, 0L);
/* if (result == 0) result = VDSetPlayThruDestination(gti, aPixMapHandle, &r1, 0L, 0L);*/ /* Use this to inset the video */
#endif
DisposHandle((Handle)aPixMapHandle);
/* Throw up an alert if there was a problem */
if (result)ErrAlert(result,(char *)"\pUpdateVDDestination");
return (result);
}
pascal long TestBuffers() {
VdigBufferRec b0, b1, b2;
VdigBufferRecListHandle h;
Ptr p;
Handle storage;
long retstat;
Rect r;
short i;
p = NewPtr (3 * sizeof(VdigBufferRec));
h = (VdigBufferRecListHandle) NewHandle (sizeof(VdigBufferRecList) +
3 * sizeof(VdigBufferRec));
retstat = VDGetMaxAuxBuffer(gti, &b0.dest, &r);
/* Initialize 3 buffers */
/* b0.nextDest = NewPixMap();
(**b0.nextDest).baseAddr = (Ptr)0xF9900000;
*/
retstat = VDGetMaxAuxBuffer(gti, &b0.dest, &r);
SetPt (&b0.location, -200, 0);
b0.reserved = 0;
/* b1.nextDest = NewPixMap();
(**b1.nextDest).baseAddr = (Ptr)0xFaa00000;
*/
retstat = VDGetMaxAuxBuffer(gti, &b1.dest, &r);
SetPt (&b1.location, -400, 0);
b1.reserved = 0;
/* b2.nextDest = NewPixMap();
(**b2.nextDest).baseAddr = (Ptr)0xFbb00000;
*/
retstat = VDGetMaxAuxBuffer(gti, &b2.dest, &r);
SetPt (&b2.location, -600, 0);
b2.reserved = 0;
/* Copy to the real buffer list pointer */
(**h).count = 3;
BlockMove(&b0, (**h).list, sizeof(VdigBufferRec));
BlockMove(&b1, (**h).list + 1, sizeof(VdigBufferRec));
BlockMove(&b2, (**h).list + 2, sizeof(VdigBufferRec));
/* An alternate way ... of doing it */
/* BlockMove(&b0, p, sizeof(VdigBufferRec));
BlockMove(&b1, p + sizeof(VdigBufferRec), sizeof(VdigBufferRec));
BlockMove(&b2, p + 2*sizeof(VdigBufferRec), sizeof(VdigBufferRec));
(**h).list[0] = *(VdigBufferRec *)p;
(**h).list[1] = *(VdigBufferRec *)(p + sizeof(VdigBufferRec));
(**h).list[2] = *(VdigBufferRec *)(p + 2*sizeof(VdigBufferRec));
*/
/* Simulate the new call */
retstat = VDSetupBuffers(gti, h);
for (i=0; i<30; i++) {
retstat = VDGrabOneFrameAsync2(gti,1);
while (!VDDone2(gti,0));
retstat = VDGrabOneFrameAsync2(gti,2);
while (!VDDone2(gti,1));
retstat = VDGrabOneFrameAsync2(gti,0);
while (!VDDone2(gti,2));
}
DisposPtr(p);
DisposHandle((Handle)h);
/* DisposPixMap(b0.nextDest);
DisposPixMap(b1.nextDest);
DisposPixMap(b2.nextDest);
*/
}
/* ======================================================= */
void RectLocalToGlobal(Rect *r)
{
Point pt;
pt.v = r->top;
pt.h = r->left;
LocalToGlobal(&pt);
r->top = pt.v;
r->left = pt.h;
pt.v = r->bottom;
pt.h = r->right;
LocalToGlobal(&pt);
r->bottom = pt.v;
r->right = pt.h;
}
/* ======================================================= */
void RectGlobalToLocal(Rect *r)
{
Point pt;
pt.v = r->top;
pt.h = r->left;
GlobalToLocal(&pt);
r->top = pt.v;
r->left = pt.h;
pt.v = r->bottom;
pt.h = r->right;
GlobalToLocal(&pt);
r->bottom = pt.v;
r->right = pt.h;
}